module entropy_lib

contains

real function entropy(dist, numbins)

	! Declare inputs
	integer, intent(in) :: numbins
	real, intent(in), dimension(0:numbins) :: dist
	
	! Declare local variables
	integer :: i
	
	entropy = 0.0
	
	do i = 0, numbins
		if(dist(i) > 0.0) then
			entropy = entropy - (dist(i)*log(dist(i)))
		end if
	enddo

	entropy = entropy / log(2.0)

	if(entropy < 0.0) then
		entropy = 0.0
	end if

end function entropy


real function jointentropy(dist, numbinsa, numbinsb)

	! Declare inputs
	integer, intent(in) :: numbinsa, numbinsb
	real, intent(in), dimension(0:numbinsa, 0:numbinsb) :: dist
	
	! Declare local variables
	integer :: i, j
	
	jointentropy = 0.0
	
	do i = 0, numbinsa
		do j = 0, numbinsb
			if(dist(i,j) > 0.0) then
				jointentropy = jointentropy - (dist(i,j)*log(dist(i,j)))
			end if
		enddo
	enddo

	jointentropy = jointentropy / log(2.0)

	if(jointentropy < 0.0) then 
		jointentropy = 0.0
	end if

end function jointentropy


real function tripleentropy(dist, numbinsa, numbinsb, numbinsc)

	! Declare inputs
	integer, intent(in) :: numbinsa, numbinsb, numbinsc
	real, intent(in), dimension(0:numbinsa, 0:numbinsb, 0:numbinsc) :: dist
	
	! Declare local variables
	integer :: i, j, k
	
	tripleentropy = 0.0
	
	do i = 0, numbinsa
		do j = 0, numbinsb
			do k = 0, numbinsc
				if(dist(i,j,k) > 0.0) then
					tripleentropy = tripleentropy - (dist(i,j,k)*log(dist(i,j,k)))
				end if
			enddo
		enddo
	enddo

	tripleentropy = tripleentropy / log(2.0)


	if(tripleentropy < 0.0) then
		tripleentropy = 0.0
	end if

end function tripleentropy





end module entropy_lib
